#include <iostream>
#include <list>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>

#include "sock.hpp"
#include "sockdist.hpp"

void* threadClientEnvoi(void *arg);
void* threadClientReception(void *arg);
void* threadGenerationGrille(void *arg);
void* threadCommandes(void *arg);
void usage(FILE *stream); // Affiche le manuel
void ecritureGrille(char commande); // Ecrit dans la grille la direction donnee
void demandeControle(int client); // Gere la demande de controle d'un client
int majAttenteClients(); // Mettre a jour la grille sans quelqu'un venant d'en faire la demande

// Alloue et prepare la chaine pour le client, en ajoutant un caractere de controle
char* preparationEnvoi(char g[17], char carControle);

// Variables globales
char grille[17] = "1000000000000000";
int compteurGrille; // Tous les historiqueGrille la grille perds l'historique
int historiqueGrille;
list<int> descripteursCV;
list<int> attenteControle; // Contient les clients ayant fait la demande de controle du curseur

// Pour signaler la prise de controle d'un client sur la grille
// Vaut -1 si personne n'a le controle, le descripteur du client sinon
int controle;
int nbMouvementsMax; // Nombre de mouvements maximum par client qui a le controle
int compteur; // Nombre de mouvements restant possibles dans la grille

static pthread_mutex_t mutexDescripteurs = PTHREAD_MUTEX_INITIALIZER; // Protege la liste de descripteurs
static pthread_mutex_t mutexGrille = PTHREAD_MUTEX_INITIALIZER; // Protege l'ecriture sur la grille (exclusif pour un client)
static pthread_mutex_t mutexAttente = PTHREAD_MUTEX_INITIALIZER; // Protege la liste des clients en attente du controle

